#include "viml/value.h"
#include "viml/types.h"
#include "viml/memory_manager.h"
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <cmath>
#include <algorithm>

namespace viml {

// Value构造函数实现
Value::Value(const std::string& s) {
    auto* str_obj = new StringObject(s);
    MemoryManager::notify_allocation(); // 统计内存分配
    uint64_t ptr = reinterpret_cast<uint64_t>(str_obj);
    // 确保指针不会与类型标记冲突
    if (ptr & ~DATA_MASK) {
        throw std::runtime_error("Pointer address conflicts with NaN-boxing scheme");
    }
    bits = QNAN_MASK | TAG_STRING | ptr;
}

Value::Value(const char* s) {
    auto* str_obj = new StringObject(s);
    MemoryManager::notify_allocation(); // 统计内存分配
    uint64_t ptr = reinterpret_cast<uint64_t>(str_obj);
    // 确保指针不会与类型标记冲突
    if (ptr & ~DATA_MASK) {
        throw std::runtime_error("Pointer address conflicts with NaN-boxing scheme");
    }
    bits = QNAN_MASK | TAG_STRING | ptr;
}

// 静态创建方法
Value Value::list() {
    Value v;
    auto* list_obj = new ListObject();
    MemoryManager::notify_allocation(); // 统计内存分配
    uint64_t ptr = reinterpret_cast<uint64_t>(list_obj);
    if (ptr & ~DATA_MASK) {
        throw std::runtime_error("Pointer address conflicts with NaN-boxing scheme");
    }
    v.bits = QNAN_MASK | TAG_LIST | ptr;
    return v;
}

Value Value::dict() {
    Value v;
    auto* dict_obj = new DictObject();
    MemoryManager::notify_allocation(); // 统计内存分配
    uint64_t ptr = reinterpret_cast<uint64_t>(dict_obj);
    if (ptr & ~DATA_MASK) {
        throw std::runtime_error("Pointer address conflicts with NaN-boxing scheme");
    }
    v.bits = QNAN_MASK | TAG_DICT | ptr;
    return v;
}

Value Value::function(std::shared_ptr<Function> func) {
    Value v;
    // 在堆上存储shared_ptr
    auto* func_ptr = new std::shared_ptr<Function>(std::move(func));
    MemoryManager::notify_allocation(); // 统计内存分配
    v.bits = QNAN_MASK | TAG_FUNCTION | reinterpret_cast<uint64_t>(func_ptr);
    return v;
}

Value Value::closure(std::shared_ptr<Closure> closure) {
    Value v;
    // 在堆上存储shared_ptr
    auto* closure_ptr = new std::shared_ptr<Closure>(std::move(closure));
    MemoryManager::notify_allocation(); // 统计内存分配
    v.bits = QNAN_MASK | TAG_CLOSURE | reinterpret_cast<uint64_t>(closure_ptr);
    return v;
}

Value Value::builtin_function(const std::string& name, std::function<Value(const std::vector<Value>&)> func) {
#ifdef DEBUG_BUILD
    std::cout << "Creating builtin function value for '" << name << "'" << std::endl;
#endif
    Value v;
    auto* builtin_obj = new BuiltinFunctionObject(name, std::move(func));
    MemoryManager::notify_allocation(); // 统计内存分配
#ifdef DEBUG_BUILD
    std::cout << "Created BuiltinFunctionObject at address: " << builtin_obj << std::endl;
#endif
    uint64_t ptr = reinterpret_cast<uint64_t>(builtin_obj);
#ifdef DEBUG_BUILD
    std::cout << "Pointer value: " << ptr << std::endl;
    std::cout << "DATA_MASK: " << DATA_MASK << std::endl;
    std::cout << "Pointer & ~DATA_MASK: " << (ptr & ~DATA_MASK) << std::endl;
#endif
    if (ptr & ~DATA_MASK) {
#ifdef DEBUG_BUILD
        std::cout << "Pointer address conflicts with NaN-boxing scheme" << std::endl;
#endif
        throw std::runtime_error("Pointer address conflicts with NaN-boxing scheme");
    }
    v.bits = QNAN_MASK | TAG_BUILTIN | ptr;
#ifdef DEBUG_BUILD
    std::cout << "Created builtin function value with bits: " << v.bits << std::endl;
#endif
    return v;
}

// 类型检查实现
ValueType Value::type() const {
    if (!is_nan()) {
        return ValueType::FLOAT;
    }
    
    uint64_t tag = get_tag();
    if (tag == TAG_NIL) return ValueType::NIL;
    if (tag == TAG_NUMBER) return ValueType::NUMBER;
    if (tag == TAG_BOOLEAN) return ValueType::BOOLEAN;
    if (tag == TAG_STRING) return ValueType::STRING;
    if (tag == TAG_LIST) return ValueType::LIST;
    if (tag == TAG_DICT) return ValueType::DICT;
    if (tag == TAG_FUNCTION) return ValueType::FUNCTION;
    if (tag == TAG_CLOSURE) return ValueType::CLOSURE;
    if (tag == TAG_BUILTIN) return ValueType::BUILTIN;  // 内建函数
    if (tag == TAG_NONE) return ValueType::NONE;  // NONE类型
    
    return ValueType::NIL; // 默认
}

bool Value::is_nil() const {
    return is_nan() && get_tag() == TAG_NIL;
}

bool Value::is_none() const {
    return is_nan() && get_tag() == TAG_NONE;
}

bool Value::is_number() const {
    return is_nan() && get_tag() == TAG_NUMBER;
}

bool Value::is_float() const {
    return !is_nan();
}

bool Value::is_string() const {
    return is_nan() && get_tag() == TAG_STRING;
}

bool Value::is_boolean() const {
    return is_nan() && get_tag() == TAG_BOOLEAN;
}

bool Value::is_list() const {
    return is_nan() && get_tag() == TAG_LIST;
}

bool Value::is_dict() const {
    return is_nan() && get_tag() == TAG_DICT;
}

bool Value::is_function() const {
    return is_nan() && get_tag() == TAG_FUNCTION;
}

bool Value::is_closure() const {
    return is_nan() && get_tag() == TAG_CLOSURE;
}

bool Value::is_builtin() const {
    return is_nan() && get_tag() == TAG_BUILTIN;
}

// 值提取实现
int64_t Value::as_number() const {
    if (!is_number()) {
        throw std::runtime_error("Value is not a number");
    }
    // 正确处理负数：如果最高位是1，则表示负数
    uint64_t data = get_data();
    if (data & (1ULL << 43)) {  // 如果第43位是1（符号位）
        // 扩展符号位以获得正确的负数
        data |= 0xFFFF000000000000ULL;
    }
    return static_cast<int64_t>(data);
}

double Value::as_float() const {
    if (!is_float()) {
        throw std::runtime_error("Value is not a float");
    }
    return number;
}

bool Value::as_boolean() const {
    if (!is_boolean()) {
        throw std::runtime_error("Value is not a boolean");
    }
    return (get_data() & 1) != 0;
}

std::string Value::as_string() const {
    if (!is_string()) {
        throw std::runtime_error("Value is not a string");
    }
    auto* str_obj = reinterpret_cast<StringObject*>(get_data());
    return str_obj->get_data();
}

std::vector<Value>& Value::as_list() const {
    if (!is_list()) {
        throw std::runtime_error("Value is not a list");
    }
    auto* list_obj = reinterpret_cast<ListObject*>(get_data());
    return list_obj->get_elements();
}

std::unordered_map<std::string, Value>& Value::as_dict() const {
    if (!is_dict()) {
        throw std::runtime_error("Value is not a dict");
    }
    auto* dict_obj = reinterpret_cast<DictObject*>(get_data());
    return dict_obj->get_entries();
}

std::shared_ptr<Function> Value::as_function() const {
    if (!is_function()) {
        throw std::runtime_error("Value is not a function");
    }
    auto* func_ptr = reinterpret_cast<std::shared_ptr<Function>*>(get_data());
    return *func_ptr;
}

std::shared_ptr<Closure> Value::as_closure() const {
    if (!is_closure()) {
        throw std::runtime_error("Value is not a closure");
    }
    auto* closure_ptr = reinterpret_cast<std::shared_ptr<Closure>*>(get_data());
    return *closure_ptr;
}

const std::function<Value(const std::vector<Value>&)>& Value::as_builtin() const {
    if (!is_builtin()) {
        throw std::runtime_error("Value is not a builtin function");
    }
    auto* builtin_obj = reinterpret_cast<BuiltinFunctionObject*>(get_data());
    return builtin_obj->get_function();
}

// VimL真值语义
bool Value::is_truthy() const {
    switch (type()) {
        case ValueType::NIL:
            return false;
        case ValueType::NUMBER:
            return as_number() != 0;
        case ValueType::FLOAT:
            return as_float() != 0.0;
        case ValueType::STRING:
            return !as_string().empty();
        case ValueType::BOOLEAN:
            return as_boolean();
        case ValueType::LIST:
            return !as_list().empty();
        case ValueType::DICT:
            return !as_dict().empty();
        case ValueType::FUNCTION:
        case ValueType::CLOSURE:
        case ValueType::BUILTIN:
            return true;
        case ValueType::NONE:
            return false;
    }
    return false;
}

// 类型转换
std::string Value::to_string() const {
    switch (type()) {
        case ValueType::NIL:
            return "";
        case ValueType::NUMBER: {
            int64_t n = as_number();
            return std::to_string(n);
        }
        case ValueType::FLOAT: {
            double f = as_float();
            // VimL浮点数到字符串转换规则
            if (std::floor(f) == f && f >= -2147483648.0 && f <= 2147483647.0) {
                return std::to_string(static_cast<int64_t>(f));
            } else {
                return std::to_string(f);
            }
        }
        case ValueType::STRING:
            return as_string();
        case ValueType::BOOLEAN:
            return as_boolean() ? "1" : "0";
        case ValueType::LIST: {
            std::ostringstream oss;
            oss << "[";
            const auto& elements = as_list();
            for (size_t i = 0; i < elements.size(); ++i) {
                if (i > 0) oss << ", ";
                oss << elements[i].to_string();
            }
            oss << "]";
            return oss.str();
        }
        case ValueType::DICT: {
            std::ostringstream oss;
            oss << "{";
            const auto& entries = as_dict();
            bool first = true;
            for (const auto& pair : entries) {
                if (!first) oss << ", ";
                oss << "'" << pair.first << "': " << pair.second.to_string();
                first = false;
            }
            oss << "}";
            return oss.str();
        }
        case ValueType::FUNCTION:
            return "<function>";
        case ValueType::CLOSURE:
            return "<closure>";
        case ValueType::BUILTIN:
            return "<builtin>";
        case ValueType::NONE:
            return "";
    }
    return "";
}

int64_t Value::to_number() const {
    switch (type()) {
        case ValueType::NIL:
            return 0;
        case ValueType::NUMBER:
            return as_number();
        case ValueType::FLOAT:
            return static_cast<int64_t>(as_float());
        case ValueType::STRING: {
            const std::string& s = as_string();
            if (s.empty()) return 0;
            try {
                return static_cast<int64_t>(std::stoll(s));
            } catch (...) {
                return 0;
            }
        }
        case ValueType::BOOLEAN:
            return as_boolean() ? 1 : 0;
        case ValueType::LIST:
            return static_cast<int64_t>(as_list().size());
        case ValueType::DICT:
            return static_cast<int64_t>(as_dict().size());
        case ValueType::FUNCTION:
        case ValueType::CLOSURE:
        case ValueType::BUILTIN:
            return 0;
        case ValueType::NONE:
            return 0;
    }
    return 0;
}

double Value::to_float() const {
    switch (type()) {
        case ValueType::NIL:
            return 0.0;
        case ValueType::NUMBER:
            return static_cast<double>(as_number());
        case ValueType::FLOAT:
            return as_float();
        case ValueType::STRING: {
            const std::string& s = as_string();
            if (s.empty()) return 0.0;
            try {
                return std::stod(s);
            } catch (...) {
                return 0.0;
            }
        }
        case ValueType::BOOLEAN:
            return as_boolean() ? 1.0 : 0.0;
        case ValueType::LIST:
            return static_cast<double>(as_list().size());
        case ValueType::DICT:
            return static_cast<double>(as_dict().size());
        case ValueType::FUNCTION:
        case ValueType::CLOSURE:
        case ValueType::BUILTIN:
            return 0.0;
        case ValueType::NONE:
            return 0.0;
    }
    return 0.0;
}

// 比较操作
bool Value::operator==(const Value& other) const {
    if (type() != other.type()) {
        return false;
    }
    
    switch (type()) {
        case ValueType::NIL:
            return true;
        case ValueType::NUMBER:
            return as_number() == other.as_number();
        case ValueType::FLOAT:
            return as_float() == other.as_float();
        case ValueType::STRING:
            return as_string() == other.as_string();
        case ValueType::BOOLEAN:
            return as_boolean() == other.as_boolean();
        case ValueType::LIST:
            return as_list() == other.as_list();
        case ValueType::DICT:
            return as_dict() == other.as_dict();
        case ValueType::FUNCTION:
        case ValueType::CLOSURE:
        case ValueType::BUILTIN:
            return bits == other.bits; // 指针比较
        case ValueType::NONE:
            return true; // 所有NONE值都相等
    }
    return false;
}

bool Value::operator!=(const Value& other) const {
    return !(*this == other);
}

bool Value::operator<(const Value& other) const {
    // VimL比较规则：先按类型，再按值
    if (type() != other.type()) {
        return static_cast<int>(type()) < static_cast<int>(other.type());
    }
    
    switch (type()) {
        case ValueType::NIL:
            return false;
        case ValueType::NUMBER:
            return as_number() < other.as_number();
        case ValueType::FLOAT:
            return as_float() < other.as_float();
        case ValueType::STRING:
            return as_string() < other.as_string();
        case ValueType::BOOLEAN:
            return as_boolean() < other.as_boolean();
        case ValueType::LIST:
            return as_list().size() < other.as_list().size();
        case ValueType::DICT:
            return as_dict().size() < other.as_dict().size();
        case ValueType::FUNCTION:
        case ValueType::CLOSURE:
        case ValueType::BUILTIN:
            return bits < other.bits;
        case ValueType::NONE:
            return false; // 所有NONE值都相等，不存在小于关系
    }
    return false;
}

bool Value::operator<=(const Value& other) const {
    return *this < other || *this == other;
}

bool Value::operator>(const Value& other) const {
    return !(*this <= other);
}

bool Value::operator>=(const Value& other) const {
    return !(*this < other);
}

// 算术操作
Value Value::operator+(const Value& other) const {
    // 数字和浮点数加法
    if ((is_number() || is_float()) && (other.is_number() || other.is_float())) {
        // 如果任何一个是浮点数，结果为浮点数
        if (is_float() || other.is_float()) {
            return Value::make_float(to_float() + other.to_float());
        } else {
            return Value::make_number(to_number() + other.to_number());
        }
    }
    
    // 字符串连接
    if (is_string() || other.is_string()) {
        return Value::string(to_string() + other.to_string());
    }
    
    // 列表连接
    if (is_list() && other.is_list()) {
        auto result = Value::list();
        auto& result_list = result.as_list();
        const auto& left_list = as_list();
        const auto& right_list = other.as_list();
        
        result_list.insert(result_list.end(), left_list.begin(), left_list.end());
        result_list.insert(result_list.end(), right_list.begin(), right_list.end());
        return result;
    }
    
    // 默认数字转换
    return Value::make_float(to_float() + other.to_float());
}

Value Value::operator-(const Value& other) const {
    // 如果任何一个是浮点数，结果为浮点数
    if ((is_number() || is_float()) && (other.is_number() || other.is_float())) {
        if (is_float() || other.is_float()) {
            return Value::make_float(to_float() - other.to_float());
        } else {
            return Value::make_number(to_number() - other.to_number());
        }
    }
    return Value::make_float(to_float() - other.to_float());
}

Value Value::operator*(const Value& other) const {
    // 如果任何一个是浮点数，结果为浮点数
    if ((is_number() || is_float()) && (other.is_number() || other.is_float())) {
        if (is_float() || other.is_float()) {
            return Value::make_float(to_float() * other.to_float());
        } else {
            return Value::make_number(to_number() * other.to_number());
        }
    }
    return Value::make_float(to_float() * other.to_float());
}

Value Value::operator/(const Value& other) const {
    double divisor = other.to_float();
    if (divisor == 0.0) {
        throw std::runtime_error("Division by zero");
    }
    // 除法总是返回浮点数
    return Value::make_float(to_float() / divisor);
}

Value Value::operator%(const Value& other) const {
    double divisor = other.to_float();
    if (divisor == 0.0) {
        throw std::runtime_error("Division by zero");
    }
    return Value::make_float(std::fmod(to_float(), divisor));
}

Value Value::operator-() const {
    if (is_number()) {
        return Value::make_number(-as_number());
    } else if (is_float()) {
        return Value::make_float(-as_float());
    }
    return Value::make_float(-to_float());
}

// 逻辑操作
Value Value::operator&&(const Value& other) const {
    return Value::boolean(is_truthy() && other.is_truthy());
}

Value Value::operator||(const Value& other) const {
    return Value::boolean(is_truthy() || other.is_truthy());
}

Value Value::operator!() const {
    return Value::boolean(!is_truthy());
}

// 索引操作
Value Value::operator[](const Value& key) const {
    if (is_list()) {
        size_t index = static_cast<size_t>(key.to_number());
        const auto& list = as_list();
        if (index >= list.size()) {
            throw std::runtime_error("List index out of range");
        }
        return list[index];
    } else if (is_dict()) {
        const auto& dict = as_dict();
        std::string key_str = key.to_string();
        auto it = dict.find(key_str);
        if (it == dict.end()) {
            return Value::nil();
        }
        return it->second;
    }
    throw std::runtime_error("Value is not indexable");
}

Value& Value::operator[](const Value& key) {
    if (is_list()) {
        size_t index = static_cast<size_t>(key.to_number());
        auto& list = as_list();
        if (index >= list.size()) {
            throw std::runtime_error("List index out of range");
        }
        return list[index];
    } else if (is_dict()) {
        auto& dict = as_dict();
        std::string key_str = key.to_string();
        return dict[key_str];
    }
    throw std::runtime_error("Value is not indexable");
}

// 调试输出
std::string Value::debug_string() const {
    std::ostringstream oss;
    oss << "Value{type=" << static_cast<int>(type()) << ", ";
    
    switch (type()) {
        case ValueType::NIL:
            oss << "nil";
            break;
        case ValueType::NUMBER:
            oss << "number=" << as_number();
            break;
        case ValueType::FLOAT:
            oss << "float=" << as_float();
            break;
        case ValueType::STRING:
            oss << "string=\"" << as_string() << "\"";
            break;
        case ValueType::BOOLEAN:
            oss << "boolean=" << (as_boolean() ? "true" : "false");
            break;
        case ValueType::LIST:
            oss << "list[" << as_list().size() << "]";
            break;
        case ValueType::DICT:
            oss << "dict[" << as_dict().size() << "]";
            break;
        case ValueType::FUNCTION:
            oss << "function";
            break;
        case ValueType::CLOSURE:
            oss << "closure";
            break;
        case ValueType::BUILTIN:
            oss << "builtin";
            break;
        case ValueType::NONE:
            oss << "none";
            break;
    }
    
    oss << "}";
    return oss.str();
}

// 内部辅助方法
bool Value::is_nan() const {
    return (bits & QNAN_MASK) == QNAN_MASK;
}

uint64_t Value::get_tag() const {
    return bits & TYPE_MASK;
}

uint64_t Value::get_data() const {
    return bits & DATA_MASK;
}

Object* Value::get_object() const {
    return reinterpret_cast<Object*>(get_data());
}

void Value::set_object(Object* obj) {
    bits = (bits & ~DATA_MASK) | reinterpret_cast<uint64_t>(obj);
}

} // namespace viml